﻿using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace FinalPointSet.Model.Model.FieldMapping
{
    public class SQLParser
    {
        /// <summary>
        /// 解析传入的字段字符串为Table
        /// </summary>
        /// <param name="sql">待解析的字段字符串</param>
        /// <param name="tableName">表名</param>
        /// <param name="database">库名</param>
        /// <param name="comment">备注</param>
        /// <returns></returns>
        public static Table StringToTable(string sql, string tableName, string database, string comment)
        {
            Table table = new()
            {
                Name = tableName,
                Database = database,
                Comment = comment,
                Fields = StringToFields(sql)
            };

            return table;
        }

        /// <summary>
        /// 根据文本,解析字段
        /// </summary>
        /// <param name="strField">待解析的文本</param>
        /// <returns>字段</returns>
        public static Field StringToField(string strField)
        {
            //1、提取字段除了Comment之外的属性
            string s_field = Regex.Replace(strField, @"\s+", " ")
                                  .Replace(",", " ")
                                  .Replace(" (", "(")
                                  .Replace("( ", "(")
                                  .Replace(" )", ")");
            string[] s_arr_split = s_field.Split(" ");
            Field field = new();
            int i_cur_cnt = 0;
            //根据空格切分字符串,循环提取
            foreach (string word in s_arr_split)
            {
                //碰到comment直接退出, 不在这里做解析
                if (word.Equals("comment")) break;
                //碰到comment写入不规范直接退出, 不在这里做解析
                if (word.Contains("comment") && i_cur_cnt > 1) break;
                //空字符直接跳过检测
                if (word.Length == 0) continue;

                //字段名称
                if (i_cur_cnt == 0)
                {
                    i_cur_cnt++;
                    field.Name = word.Replace("`", "");
                }
                //字段类型名称+类型整数位
                else if (i_cur_cnt == 1)
                {
                    i_cur_cnt++;
                    string s_filter_nullable = word
                                                .Replace("nullable(", "") //兼容clickhouse的Nullable字段属性
                                                .Replace(")", "");
                    string[] s_arr_type = s_filter_nullable.Split("(");
                    field.Type = Regex.Replace(s_arr_type[0], @"\s+", ""); //提取类型
                    if (s_filter_nullable.Contains('('))
                    {
                        field.Integer = int.Parse(s_arr_type[1].Replace(")", "").Replace(" ", ""));
                    }
                }
                //字段类型小数位
                else if (i_cur_cnt == 2)
                {
                    //判断类型是否带小数位
                    if (word.Contains(')'))
                    {
                        string[] s_arr_type = word.Split(")");
                        if (s_arr_type[0].Length > 0)
                        {
                            field.Decimal = int.Parse(s_arr_type[0]);
                        }
                        i_cur_cnt++;
                    }
                }
            }

            //2、提取Comment
            if (strField.Contains("comment") && strField.Contains('\''))
            {
                //剔除空格、制表符、换行符
                string filterFiled = strField.Replace(" ", "");
                string[] s_arr_comment = filterFiled.Split("comment");
                foreach (string item in s_arr_comment)
                {
                    if (item.StartsWith('\''))
                    {
                        field.Comment = item.Split("'")[1].Replace("'", "");
                    }
                }

            }
            return field;
        }

        /// <summary>
        /// 根据提供的SQL,获取字段集合
        /// </summary>
        /// <param name="sql">待解析的SQL</param>
        /// <returns>字段集合</returns>
        public static List<Field> StringToFields(string sql)
        {
            //1.copy字符串
            string s_src_sql = new(sql);
            List<Field> list_cls_fields = [];

            //2.进行清洗
            s_src_sql = s_src_sql
                .ToLower()
                .Replace("\r\n", "\n")           //统一换行符
                .Replace("\t", " ");             //剔除制表符

            //3.根据换行符,切割文本
            string[] s_arr_split_lines = s_src_sql.Split('\n');

            //3.1剔除整行都是空格的情况
            List<string> list_real_line = [];
            for (int i = 0; i < s_arr_split_lines.Length; i++)
            {
                string result = s_arr_split_lines[i].Replace(" ", "");
                if (result.Length > 0)
                    list_real_line.Add(s_arr_split_lines[i]);
            }

            foreach (string s_line in list_real_line)
            {
                Field cls_field = StringToField(s_line);
                list_cls_fields.Add(cls_field);
            }

            //4.返回字段
            return list_cls_fields;
        }
    }
}
